﻿/*
 *********************************************************************
 *    Management Extensions for Windows Windows Server AppFabric     *
 *********************************************************************
 *    Author    : Fatih Boy [fatih@enterprisecoding.com]             *
 *    Web site  : http://www.enterprisecoding.com                    *
 *********************************************************************
 *    License   : GNU Library General Public License (LGPL)          * 
 *********************************************************************
 */

using Com.Enterprisecoding.AppFabric.Extensions.Powershell;
using Microsoft.Web.Management.Server;
using System;
using System.IO;

namespace Com.Enterprisecoding.AppFabric.Extensions.Services {
    internal sealed class CacheConfigBackupService : ChildServiceBase {
        private int serializationBufferSize = 262140;

        public void UploadCacheClusterConfig(Guid configFileGuid, byte[] fileContent) {
            var tempFile = Path.Combine(Path.GetTempPath(), configFileGuid.ToString() + ".tmp");

            using (var tempFileStream = new FileStream(tempFile, FileMode.OpenOrCreate)) {
                tempFileStream.Write(fileContent, 0, fileContent.Length);
            }
        }

        public void ImportCacheClusterConfig(Guid configFileGuid) {
            var tempFile = Path.Combine(Path.GetTempPath(), configFileGuid.ToString() + ".tmp");

            if (File.Exists(tempFile)) {
                var host = new PowershellHost();

                try {
                    host.AddCommand("Use-CacheCluster");
                    host.AddCommand("Import-CacheClusterConfig");
                    host.AddParameter("File", tempFile);
                    host.AddParameter("Force");

                    host.Invoke();
                }
                finally {
                    if (File.Exists(tempFile)) {
                        File.Delete(tempFile);
                    }
                }
            }
        }

        public PropertyBag ExportCacheClusterConfig() {
            var host = new PowershellHost();
            var tempFileGuid = Guid.NewGuid();
            var tempFileFullPath = Path.Combine(Path.GetTempPath(), tempFileGuid.ToString() + ".tmp");

            host.AddCommand("Use-CacheCluster");
            host.AddCommand("Export-CacheClusterConfig");
            host.AddParameter("File", tempFileFullPath);

            host.Invoke();

            var bag = new PropertyBag();
            bag[0] = tempFileGuid;

            return bag;
        }

        public PropertyBag DownloadCacheClusterConfig(Guid configFileGuid, long startIndex) {
            try {
                var tempFileFullPath = Path.Combine(Path.GetTempPath(), configFileGuid.ToString() + ".tmp");

                var bag = new PropertyBag();

                using (var tempFileStream = File.OpenRead(tempFileFullPath)) {
                    var buffer = new byte[serializationBufferSize];

                    if (startIndex != 0) {
                        tempFileStream.Seek(startIndex, SeekOrigin.Begin);
                    }

                    var count = tempFileStream.Read(buffer, 0, buffer.Length);
                    if (count < buffer.Length) {
                        var dst = new byte[count];
                        Buffer.BlockCopy(buffer, 0, dst, 0, count);
                        buffer = dst;
                        bag[0] = true;
                    }
                    else {
                        bag[0] = false;
                    }

                    bag[1] = buffer;
                }

                return bag;
            }
            catch (IOException) { }

            return null;
        }

        public void ClearCacheClusterConfigExportFile(Guid configFileGuid) {
            var tempFileFullPath = Path.Combine(Path.GetTempPath(), configFileGuid.ToString() + ".tmp");

            if (File.Exists(tempFileFullPath)) {
                File.Delete(tempFileFullPath);
            }
        }
    }
}